<template>
  <view :="fv.rootProps">
    <scroll-view :="fv.scrollProps">
      <view :class="[variables.ns.e('wrapper')]"></view>
      <view :class="[variables.ns.e('content')]">
        <slot></slot>
      </view>
    </scroll-view>
  </view>
</template>

<script lang="ts" setup>
import { getElementInfo } from '@/utils'
import { TabNS, variables} from '.'
import { reactive, provide, computed, nextTick, watch } from 'vue'
import { get, isObject } from 'lodash'
import { v4 } from 'uuid'

defineOptions({
  name: TabNS.name
})
const props = defineProps(TabNS.props)
const emits = defineEmits(TabNS.emits)
const state = reactive({
  rootSize: '100%',
  tabItem: <UniApp.NodeInfo>{},
  childList: new Set(),
  wrapperPosition: 0
})
const provideContext: variables.ProvideContext = {
  isActive(param) {
    const key = props.valueKey!
    let mv, v
    if (isObject(param.value)) {
      mv = get(props.modelValue, key)
      v = get(param.value, key)
    } else {
      mv = props.modelValue
      v = param.value
    }

    const is = mv === v
    if (is) computedNodeInfo()
    state.childList.add(v)
    return is
  },
  change(param) {
    if (param.disabled || this.isActive(param)) return
    const value = param.value
    emits('update:modelValue', value)
    emits('change', value)
  },
  props
}
provide(variables.provideName, provideContext)
const fv = computed(() => {
  const onlyId = variables.ns.r(v4())
  const isX = props.direction === 'x'
  const rootProps = {
    class: [
      variables.ns.b,
      variables.ns.r(props.direction),
      variables.ns.r(props.styleType),
      onlyId,
      variables.ns.s('fill-up', props.isFillUp)
    ],
    style: {
      [variables.ns.getCssVarName('size')]: state.rootSize,
      [variables.ns.getCssVarName('itemWidth')]: state.tabItem.width + 'px',
      [variables.ns.getCssVarName('itemHeight')]: state.tabItem.height + 'px',
      [variables.ns.getCssVarName('wrapperPosition')]: state.wrapperPosition + 'px'
    }
  }
  const scrollProps = {
    scrollX: isX,
    scrollY: !isX,
    'show-scrollbar': false,
    'enable-flex': true,
    scrollWithAnimation: true,
    class: [
      variables.ns.e('scroll'),
    ],
  }
  // set(scrollProps, isX ? 'scrollLeft' : 'scrollTop', state.wrapperPosition)
  return {
    rootProps,
    scrollProps,
    onlyId,
    isX
  }
})

async function computedNodeInfo() {
  await nextTick()
  const { onlyId } = fv.value
  const prev = '.' + onlyId + ' .'
  const [
    [contentNode],
    [activeItem],
    scrollNode
  ] = await Promise.all([
    getElementInfo(prev + variables.ns.e('content')),
    getElementInfo(prev + variables.ns.s('active')),
    new Promise<RequiredDeep<UniApp.NodeInfo>>(resolve => {
      uni.createSelectorQuery().select(prev + variables.ns.e('scroll'))
        .fields(
          { scrollOffset: true, rect: true, size: true },
          res => resolve(res as any)
        ).exec()
    })
  ])

  if (!activeItem) return 
  
  state.tabItem = activeItem
  if (fv.value.isX) {
    state.rootSize = scrollNode.width >= contentNode.width ? 'fit-content' : '100%'
    state.wrapperPosition = scrollNode.scrollLeft - (scrollNode.left - state.tabItem.left!)
    return 
  }
  state.wrapperPosition = scrollNode.scrollTop - (scrollNode.top - state.tabItem.top!)
}

watch(() => state.childList, () => {
  state.rootSize = '100%'
  computedNodeInfo()
}, { deep: true })
</script>